package com.t2t.top.devops.service.impl;

import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.t2t.top.base.exception.ServiceException;
import com.t2t.top.devops.constant.DevopsConstants;
import com.t2t.top.devops.dao.MenuMapper;
import com.t2t.top.devops.model.dto.MenuDto;
import com.t2t.top.devops.model.po.Menu;
import com.t2t.top.devops.model.po.MenuExample;
import com.t2t.top.devops.service.MenuService;
import com.t2t.top.devops.util.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.lang.reflect.InvocationTargetException;
import java.util.*;

/**
 * @author yangpengfei
 */
@Service
@Transactional(rollbackFor = ServiceException.class)
public class MenuServiceImpl implements MenuService {

    protected Logger logger = LoggerFactory.getLogger(MenuServiceImpl.class);

    @Resource
    private MenuMapper menuMapper;


    public void delete(String ids) throws ServiceException {
        String[] arr = ids.split(",");
        for (int i = 0; i < arr.length; i++) {
            Menu po = (Menu) menuMapper.selectByPrimaryKey(Integer.parseInt(arr[i]));
            menuMapper.deleteByPrimaryKey(po.getId());
        }
    }

    @Override
    public List<MenuDto> listAllCanUseMenus() throws ServiceException {
        Menu query = new Menu();
        query.setCanUse(DevopsConstants.RECORD_STATUS_CAN_USE);
        List<Menu> menus = query(query);

        List<MenuDto> dtos = new ArrayList();
        List<Menu> firstLevelMenus = filterFirstLevelMenus(menus);
        for (Menu m : firstLevelMenus) {
            MenuDto p =  getMenuDto(m);
            List<MenuDto> items = new ArrayList();
            for (Menu mm : menus) {
                if (p.getId() == mm.getPid()) {
                    MenuDto dto = getMenuDto(mm);
                    items.add(dto);
                }
            }
            p.setChildren(items);
            dtos.add(p);
        }
        return dtos;
    }

    private MenuDto getMenuDto(Menu menu) {
        MenuDto dto = new MenuDto();
        try {
            org.apache.commons.beanutils.BeanUtils.copyProperties(dto, menu);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return dto;
    }

    private List<Menu> filterFirstLevelMenus(List<Menu> menus) {
        List list = new ArrayList();
        for (Menu m : menus) {
            if (m.getPid() == -1) {
                list.add(m);
            }
        }
        return list;
    }

    public List<MenuDto> listCanUseMenusByPid(Integer pid) throws ServiceException {
        Menu query = new Menu();
        query.setCanUse(DevopsConstants.RECORD_STATUS_CAN_USE);
        query.setPid(pid);
        List<MenuDto> menus = query(query);
        return menus;
    }

    public void update(Menu menu) throws ServiceException {
        try {
            menu.setType((menu.getPid() == -1) ? DevopsConstants.RECORD_TYPE_MENU : DevopsConstants.RECORD_TYPE_URL);
            if (menu.getId() == null || menu.getId() == 0) {
                menu.setCreateTime(new Date());
                menu.setCanUse(DevopsConstants.RECORD_STATUS_CAN_USE);
                menuMapper.insertSelective(menu);
            } else {
                menuMapper.updateByPrimaryKeySelective(menu);
            }
        } catch (Exception e) {
            throw new ServiceException(e);
        }
    }

    public List query(Menu menu) throws ServiceException {
        MenuExample e = new MenuExample();
        if (StringUtils.isNotEmpty(menu.getName())) {
            e.createCriteria().andNameLike(menu.getName());
        }

        e.createCriteria().andCanUseEqualTo(DevopsConstants.RECORD_STATUS_CAN_USE);
        return menuMapper.selectByExample(e);
    }

    @Override
    public Integer orderNum(Integer pid) throws ServiceException {
        Integer max = menuMapper.orderNum(pid);
        max = (max == null) ? 1 : max + 1;
        return max;
    }

    @Override
    public Menu findById(Integer id) throws ServiceException {
        return menuMapper.selectByPrimaryKey(id);
    }
}
